package com.myzk.example.utils.common;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.net.*;
import java.util.Enumeration;


public class IpUtils {

	private static final Logger LOG = LoggerFactory.getLogger(IpUtils.class);
	private static String localIp = null;
	
	private IpUtils(){}

	static {
		// 优先从环境变量中获取,DCE_SERVER_IP环境变量在Docker容器启动由setEnv.sh脚本设置
		localIp = getLinuxLocalIp();
		if(localIp==null || localIp.isEmpty()) {
			localIp = "127.0.0.1";
		}
	}

	/**
	 * 获取本地IP地址
	 */
	public static String getLocalIp() {
		return localIp;
	}

	/**
	 * 判断操作系统是否是Windows
	 * 
	 * @return
	 */
	public static boolean isWindowsOS() {
		boolean isWindowsOS = false;
		String osName = System.getProperty("os.name");
		if (osName.toLowerCase().indexOf("windows") > -1) {
			isWindowsOS = true;
		}
		return isWindowsOS;
	}

	/**
	 * 获取本地Host名称
	 */
	public static String getLocalHostName() throws UnknownHostException {
		return InetAddress.getLocalHost().getHostName();
	}

	/**
	 * 获取Window下的IP地址
	 */
	private static String getWindowLocalIp() {
		try {
			return InetAddress.getLocalHost().getHostAddress();
		} catch (UnknownHostException e) {
			// e.printStackTrace();
			LOG.error("获取本地IP地址异常", e);
			return "127.0.0.1";
		}
	}

	/**
	 * 获取Linux下的IP地址
	 * 
	 * @return IP地址
	 * @throws SocketException
	 */
	private static String getLinuxLocalIp() {
		String localIp = null;
		InetAddress ip = null;
		try {
			Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces(); // 获得网络接口
			while (allNetInterfaces.hasMoreElements()) { // 遍历所有的网络接口
				NetworkInterface netInterface = allNetInterfaces.nextElement();
				// String name = netInterface.getName();
				Enumeration<InetAddress> addresses = netInterface.getInetAddresses(); // 同样再定义网络地址枚举类
				while (addresses.hasMoreElements()) {
					ip = addresses.nextElement();
					if (ip != null && (ip instanceof Inet4Address)) { // InetAddress类包括Inet4Address和Inet6Address
						if (!"127.0.0.1".equals(ip.getHostAddress())) {
							localIp = ip.getHostAddress();
							break;
						}
					}
				}
			}

		} catch (SocketException ex) {
			// ex.printStackTrace();
			LOG.error("获取本机ip地址异常", ex);
		}
		return StringUtil.isEmpty(localIp) ? "127.0.0.1" : localIp;
	}

	/**
	 * 根据网络接口获取IP地址
	 * 
	 * @param ethNum
	 *            网络接口名，Linux下是eth0
	 * @return
	 */
	private String getIpByEthNum(String ethNum) {
		try {
			Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
			InetAddress ip;
			while (allNetInterfaces.hasMoreElements()) {
				NetworkInterface netInterface = allNetInterfaces.nextElement();
				if (ethNum.equals(netInterface.getName())) {
					Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
					while (addresses.hasMoreElements()) {
						ip = addresses.nextElement();
						if (ip != null && ip instanceof Inet4Address) {
							return ip.getHostAddress();
						}
					}
				}
			}
		} catch (SocketException e) {
			LOG.error(e.getMessage(), e);
		}
		return "获取服务器IP错误";
	}

	/**
	 * 获取用户真实IP地址，不使用request.getRemoteAddr();的原因是有可能用户使用了代理软件方式避免真实IP地址,
	 * 可是，如果通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP值，究竟哪个才是真正的用户端的真实IP呢？
	 * 答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。 如：X-Forwarded-For：192.168.1.110,
	 * 192.168.1.120, 192.168.1.130, 192.168.1.100 用户真实IP为： 192.168.1.110
	 * 
	 * @param request
	 * @return
	 */
	public static String getClientIp(HttpServletRequest request) {
		String ip = request.getHeader("X-Forwarded-For");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_X_FORWARDED_FOR");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("X-Real-Ip");
		}
//		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
//			ip = request.getHeader("Proxy-Client-IP");
//		}
//		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
//			ip = request.getHeader("WL-Proxy-Client-IP");
//		}
//		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
//			ip = request.getHeader("HTTP_CLIENT_IP");
//		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		// 对于通过多个代理的情况，第一个Ip为客户端真实的Ip，多个Ip按，分割
		if (ip != null && ip.indexOf(",") > 0) {
			ip = ip.substring(0, ip.indexOf(","));
		}
		return ip;
	}
}
